﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Eneter.Messaging.EndPoints.TypedMessages;
using Eneter.Messaging.MessagingSystems.MessagingSystemBase;
using Eneter.Messaging.MessagingSystems.TcpMessagingSystem;
using System.Threading;

namespace AnalyseServer
{
    // Request message type
    public class MyRequest
    {
        public byte[] Data { get; set; }
    }

    // Response message type
    public class MyResponse
    {
        public int Length { get; set; }
    }

    public class EneterDataServer
    {
        public event EventHandler OnDataReceived;

        String serverIp = "192.168.1.51";
        int serverPort = 8060;

        private IDuplexTypedMessageReceiver<MyResponse, MyRequest> myReceiver;
        EventWaitHandle waitHandle = new AutoResetEvent(false);

        public EneterDataServer()
        {
            
        }

        public EneterDataServer(string ip, int port)
        {
            serverIp = ip;
            serverPort = port;
        }

        public void StartServer()
        {
            if (myReceiver != null)
                return;

            Thread thread = new Thread(new ThreadStart(DoStartServer));
            thread.Start();
        }

        public void StopServer()
        {
            waitHandle.Set();
        }

        // It is called when a message is received.
        private void OnMessageReceived(object sender,
              TypedRequestReceivedEventArgs<MyRequest> e)
        {
            //Console.WriteLine("Received: " + e.RequestMessage.Data);
            OnDataReceived(e.RequestMessage.Data, null);

            // Create the response message.
            MyResponse aResponse = new MyResponse();
            aResponse.Length = e.RequestMessage.Data.Length;

            // Send the response message back to the client.
            myReceiver.SendResponseMessage(e.ResponseReceiverId, aResponse);
        }

        public void DoStartServer()
        {
            // Create message receiver receiving 'MyRequest' and receiving 'MyResponse'.
            IDuplexTypedMessagesFactory aReceiverFactory = new DuplexTypedMessagesFactory();
            myReceiver = aReceiverFactory.CreateDuplexTypedMessageReceiver<MyResponse, MyRequest>();

            // Subscribe to handle messages.
            myReceiver.MessageReceived += OnMessageReceived;            

            String chanel = String.Format("tcp://{0}:{1}/", serverIp, serverPort);
            // Create TCP messaging.
            IMessagingSystemFactory aMessaging = new TcpMessagingSystemFactory();
            IDuplexInputChannel anInputChannel =
               aMessaging.CreateDuplexInputChannel(chanel);

            // Attach the input channel and start to listen to messages.
            myReceiver.AttachDuplexInputChannel(anInputChannel);

            //wait for event
            waitHandle.WaitOne();

            // Detach the input channel and stop listening.
            // It releases the thread listening to messages.
            myReceiver.DetachDuplexInputChannel();
        }
    }
}
